package com.example.javapracticaltraining.scheduler;

import com.example.javapracticaltraining.entity.dto.HealthReport;
import com.example.javapracticaltraining.entity.pojo.AiHealthReport;
import com.example.javapracticaltraining.entity.pojo.Elderly;
import com.example.javapracticaltraining.service.AiHealthReportService;
import com.example.javapracticaltraining.service.ElderlyService;
import com.example.javapracticaltraining.service.SmartHealthService;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 健康报告定时任务
 * 在每天零点，每周一零点，每月一号零点，为病人生成对应的日报，周报，月报
 * 同时使用RabbitMQ将报告消息入栈，并通过MailQueueListener中的sendMail方法发送邮件
 */
@Component
public class HealthReportScheduler {

    private static final Logger logger = LoggerFactory.getLogger(HealthReportScheduler.class);

    @Resource
    private ElderlyService elderlyService;

    @Resource
    private SmartHealthService smartHealthService;

    @Resource
    private AiHealthReportService aiHealthReportService;

    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * 每天零点生成日报
     * cron表达式：秒 分 时 日 月 周
     */
    @Scheduled(cron = "0 0 0 * * *")
    public void generateDailyReports() {
        logger.info("开始生成每日健康报告...");
        generateReports("daily");
        logger.info("每日健康报告生成完成");
    }

    /**
     * 每周一零点生成周报
     * cron表达式：秒 分 时 日 月 周(1-7，1代表周一)
     */
    @Scheduled(cron = "0 0 0 * * 1")
    public void generateWeeklyReports() {
        logger.info("开始生成每周健康报告...");
        generateReports("weekly");
        logger.info("每周健康报告生成完成");
    }

    /**
     * 每月一号零点生成月报
     * cron表达式：秒 分 时 日 月 周
     */
    @Scheduled(cron = "0 0 0 1 * *")
    public void generateMonthlyReports() {
        logger.info("开始生成每月健康报告...");
        generateReports("monthly");
        logger.info("每月健康报告生成完成");
    }

    /**
     * 生成指定类型的健康报告
     * @param reportType 报告类型（daily, weekly, monthly）
     */
    private void generateReports(String reportType) {
        // 获取所有老人
        List<Elderly> elderlyList = elderlyService.list();

        // 为每个老人生成报告
        for (Elderly elderly : elderlyList) {
            try {
                // 为家属生成报告
                generateAndSendReport(elderly.getElderlyId(), reportType, "family");

                // 为医生生成报告
                generateAndSendReport(elderly.getElderlyId(), reportType, "doctor");
            } catch (Exception e) {
                logger.error("为老人ID: " + elderly.getElderlyId() + " 生成" + reportType + "报告失败", e);
            }
        }
    }

    /**
     * 生成并发送健康报告
     * @param elderlyId 老人ID
     * @param reportType 报告类型
     * @param targetRole 目标角色
     */
    private void generateAndSendReport(Integer elderlyId, String reportType, String targetRole) {
        // 生成健康报告
        HealthReport healthReport = smartHealthService.generateHealthReport(elderlyId, reportType, targetRole);

        // 保存健康报告
        AiHealthReport savedReport = aiHealthReportService.saveHealthReport(healthReport, targetRole);

        // 发送报告通知到RabbitMQ队列
        sendReportNotification(elderlyId, savedReport, reportType, targetRole);
    }

    /**
     * 发送报告通知到RabbitMQ队列
     * @param elderlyId 老人ID
     * @param report 健康报告
     * @param reportType 报告类型
     * @param targetRole 目标角色
     */
    private void sendReportNotification(Integer elderlyId, AiHealthReport report, String reportType, String targetRole) {
        Map<String, Object> mailData = new HashMap<>();
        mailData.put("type", "health_report");
        mailData.put("elderlyId", elderlyId);
        mailData.put("reportId", report.getReportId());
        mailData.put("reportType", reportType);
        mailData.put("targetRole", targetRole);

        // 发送到RabbitMQ的mail队列
        rabbitTemplate.convertAndSend("mail", mailData);
        logger.info("健康报告通知已发送到队列: 老人ID=" + elderlyId + ", 报告类型=" + reportType + ", 目标角色=" + targetRole);
    }
}
